package com.songtech.server.frame.chain.handler;

import com.songtech.server.Calculation.TrailPointGrepCalculation;
import com.songtech.server.Jedis.JedisBaseDao;
import com.songtech.server.Point.PosPoint;
import com.songtech.server.constant.Calculate;
import com.songtech.server.entry.PositionProtocal;
import com.songtech.server.frame.dao.mapper.PositionServerMapper;
import com.songtech.server.utils.CalculationUtils;
import com.songtech.server.utils.FormatDateUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.io.Serializable;
import java.util.Date;

/**
 * Create By YINN on 2018/4/26 16:06
 * Description : 存储策略处理器
 */
public class StoragePolicyHandler implements BaseChainHandler {

    //距离变动范围(米)
    private static final double MIN_CHANGE_DISTANCE = 30;

    //最小变化时间(秒)
    private static final double MIN_CHANGE_TIME = 0;

    //协议实体类
    private PositionProtocal entry;

    //缓存操作接口
    private JedisBaseDao<Serializable> jedisBaseDao;

    //数据库trail表操作接口
    private PositionServerMapper positionServerMapper;


    /**
     * Created by YINN on 2018/4/27 10:35.
     * @Description : Constructor
     */
    public StoragePolicyHandler(PositionProtocal entry, JedisBaseDao<Serializable> jedisBaseDao, PositionServerMapper positionServerMapper) {

        this.entry = entry;
        this.jedisBaseDao = jedisBaseDao;
        this.positionServerMapper = positionServerMapper;

    }


    @Override
    public void exec() {

        //获取上次存储数据入mysql数据库时的定位对象的redis键,
        // 用来判断是否当前数据对象需要入mysql库(存储策略)
        String oriKey = entry.makeOriKey();
//        entry.setOriKey(oriKey);

        //原始位置存储
        PositionProtocal oriEntry = (PositionProtocal) jedisBaseDao.get(oriKey);


        if (oriEntry == null) {

            //上一点位置赋值
            jedisBaseDao.put(oriKey, entry);

        } else {

            //获取时间差
            int timeDiff = FormatDateUtils.getSeconds(oriEntry.getRecordTime(),entry.getRecordTime());

            if (timeDiff < MIN_CHANGE_TIME){
                return;
            }

            //获取位置变化距离(米)
            double distanceChange = CalculationUtils.getDistance((double) oriEntry.getLatitude() / Calculate.LON_LAT_FACTOR,
                    (double) oriEntry.getLongitude() / Calculate.LON_LAT_FACTOR,
                    (double) entry.getLatitude() / Calculate.LON_LAT_FACTOR,
                    (double) entry.getLongitude() / Calculate.LON_LAT_FACTOR);


            //添加轨迹过滤算法
            TrailPointGrepCalculation calculation = new TrailPointGrepCalculation(
                    PosPoint.instanceFactory(oriEntry),
                    PosPoint.instanceFactory(entry),
                    distanceChange
            );

            //一小时一存储 or 跨天 or （移动超过最小精确度并且 轨迹不过滤）
            if (FormatDateUtils.getMinite(oriEntry.getRecordTime().getTime(),entry.getRecordTime().getTime()) > 60
                    || (entry.getRecordTime().getDay() - oriEntry.getRecordTime().getDay() != 0)
                    || (distanceChange > MIN_CHANGE_DISTANCE && !calculation.isGrepPresentPoint()) ) {

                //存储入库
                positionServerMapper.add(entry);

                //存储入缓存
                jedisBaseDao.put(oriKey, entry);

            }


        }
    }


}
